﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ProgNetComponents.Interfaces;
using System.Drawing;
using DevExpress.XtraScheduler;
using System.Reflection;
using DevExpress.XtraEditors.Repository;
using System.Data;

namespace BuildHelper.Scheduler
{
    public class Zadanie : INamedObject
    {
        public static class Statusy
        {
            public const string Zakonczone = "Zakńczone";
            public const string Anulowane = "Anulowane";
            public const string Blad = "Błąd";
            public const string ZakonczoneZBledem = "Zakńczone z błędem";
            public const string W_Trakcie = "W trakcie";
            public const string Nieznany = "Nieznany";
        }

        public static class ZadaniaId
        {
            public const string UaktualnianieSrodowisk = "SR_UPD";
            public const string UaktualnianieBazDanych = "DB_UPD";
            public const string TortoiseUpdate = "TORTOISE_PROC_UPD";
            public const string Info = "INFO";
            public const string BudowanieGui = "GUI_BUILD";
            public const string BudowanieJavy = "JAVA_BUILD";
            public const string InternalSdk = "INTERNAL_SDK";
        }

        public const int MAX_PARAMS = 10;
        private static ZadaniaCollection _Zadania = null;
        public static ZadaniaCollection Zadania
        {
            get
            {
                if (_Zadania == null)
                {
                    _Zadania = new ZadaniaCollection();
                    Zadanie z = new Zadanie(ZadaniaId.UaktualnianieSrodowisk, "Uaktualnienie Środowisk", 
                        new Action<bool, DataRow>(Setup.Srodowiska.Tools.UpdateAllEnvs), 
                        Color.LightSkyBlue, ParamType.Bool);
                    _Zadania.Add(z);

                    z = new Zadanie(ZadaniaId.UaktualnianieBazDanych, "Uaktualnienie Baz Danych", 
                        new Action<bool, DataRow>(Setup.BazyDanych.Tools.UpdateAllDb), 
                        Color.LightGray, ParamType.Bool);
                    _Zadania.Add(z);

                    z = new Zadanie(ZadaniaId.TortoiseUpdate, "Tortoise Proc Update",
                        new Action<string, DataRow>(GlobalTools.TortoiseTools.TortoiseProcUpdate),
                        Color.Aquamarine);
                    _Zadania.Add(z);

                    z = new Zadanie(ZadaniaId.Info, "Info",
                        new Action<string,bool, DataRow>(ShowInfo),
                        Color.WhiteSmoke);
                    _Zadania.Add(z);


                    z = new Zadanie(ZadaniaId.InternalSdk, "Pobieranie Internal SDK",
                        new Action<string, bool, DataRow>(GlobalTools.FilesTools.GetBestInternalSdk),
                        Color.Cyan);
                    _Zadania.Add(z);

                    z = new Zadanie(ZadaniaId.BudowanieGui, "Budowanie GUI",
                       new Action<string, string, bool, string, string, bool, bool, DataRow>(Work.GUI.BudowanieGuiTools.Buduj),
                       Color.Lime);
                    _Zadania.Add(z);

                    z = new Zadanie(ZadaniaId.BudowanieJavy, "Budowanie Javy",
                       new Action<string, string, int, bool, bool, bool, bool, bool, DataRow>(Work.JAVA.BudowanieJavyTools.BuildPack),
                       Color.PaleGreen);
                    _Zadania.Add(z);
                }
                return _Zadania;
            }
        }
        public bool IsRowParam
        {
            get;
            set;
        }
        public static void PrepareLookupForZadania(RepositoryItemLookUpEdit lue)
        {
            lue.Columns.AddRange(new DevExpress.XtraEditors.Controls.LookUpColumnInfo[] {
            new DevExpress.XtraEditors.Controls.LookUpColumnInfo("Nazwa", "Nazwa"),
            new DevExpress.XtraEditors.Controls.LookUpColumnInfo("Id", "Id", 20, DevExpress.Utils.FormatType.None, "", false, DevExpress.Utils.HorzAlignment.Default)});
            lue.DisplayMember = "Nazwa";
            lue.NullText = "";
            lue.ValueMember = "Id";
            lue.DataSource = Zadania;
        }
        
        public static void ShowInfo(string info, bool dialog, DataRow row)
        {
            if (dialog)
                FormMain.Instance.ShowDxInfoDialog(info);
            else
                FormMain.ShowInfoAlert(info);
            if (row != null)
            {
                try
                {
                    if (FormMain.Instance.InvokeRequired)
                    {
                        FormMain.Instance.Invoke(new Action(() =>
                        {
                            row["STATUS"] = BuildHelper.Scheduler.Zadanie.Statusy.Zakonczone;
                        }));
                    }
                    else
                    {
                        row["STATUS"] = BuildHelper.Scheduler.Zadanie.Statusy.Zakonczone;
                    }
                }
                catch (Exception ex) { ex.Log(); }
            }
        }
        
        public Zadanie(string id, string nazwa, Delegate act, Color color, params ParamType[] parameters)
            : this(id, nazwa, act, parameters)
        {
            Label = new AppointmentLabel(color, nazwa);
        }
        
        public Zadanie(string id, string nazwa, Delegate act, params ParamType[] parameters)
        {
            Id = id;
            Nazwa = nazwa;
            Action = act;
            
            if (parameters != null && parameters.Length != 0)
                Parameters = parameters;

            if (act != null && act.Method != null)
            {
                ParameterInfo[] pis = act.Method.GetParameters();
                if (pis != null && pis.Length > 0)
                {
                    List<ParamType> list = new List<ParamType>();
                    foreach (ParameterInfo p in pis)
                    {
                        if (p.ParameterType == typeof(int))
                            list.Add(ParamType.Int);
                        else if (p.ParameterType == typeof(bool))
                            list.Add(ParamType.Bool);
                        else if (p.ParameterType == typeof(decimal))
                            list.Add(ParamType.Decimal);
                        else if (p.ParameterType == typeof(string))
                            list.Add(ParamType.String);
                        else if (p.ParameterType == typeof(DataRow))
                            IsRowParam = true;
                        else throw new InvalidOperationException("Parameter type " + p.ParameterType + " is not supported");
                    }
                    if (Parameters == null)
                        Parameters = list.ToArray();
                }

            }
        }
        
        public ParamType[] Parameters
        {
            get;
            set;
        }
        public object ConvertParam(object value, int paramNo)
        {
            if (Parameters != null && Parameters.Length >= paramNo)
            {
                ParamType t = Parameters[paramNo - 1];
                switch (t)
                {
                    case ParamType.Bool:
                        return value.AsBool();
                    case ParamType.Decimal:
                        return value.AsDecimal();
                    case ParamType.Int:
                        return value.AsInt();
                    case ParamType.String:
                        return value.AsString();
                }
            }
            return value;
        }

        public object[] GetRealParams(DataRow row, object[] parameters)
        {
            if (Parameters != null)
            {
                List<object> list = new List<object>();
                for (int i = 0; i < Parameters.Length; i++)
                {
                    list.Add(ConvertParam(parameters[i], i+1));
                }
                if(IsRowParam)
                    list.Add(row);
                return list.ToArray();
            }
            return null;
        }
        
        public string Id
        {
            get;
            set;
        }
        public string Nazwa
        {
            get;
            set;
        }
        public Delegate Action
        {
            get;
            set;
        }
        string INamedObject.Name
        {
            get
            {
                return Id;
            }
            set
            {
                Id = value;
            }
        }
        public AppointmentLabel Label
        {
            get;
            set;
        }
    }

    public class MultiTaskInfo
    {
        public DataRow Row
        {
            get;
            set;
        }
        public bool IsCanceled
        {
            get;
            set;
        }
    }

    public enum ParamType
    {
        String,
        Int,
        Decimal,
        Bool
    }
    public class ZadaniaCollection : ProgNetComponents.Collections.BaseNamedCollection<Zadanie>
    {
        
    }
}
